# include "MainWindow.h"
# include "ToolBar.h"
# include "SettingBar.h"
# include <QImage>
# include <QPainter>
# include<QCloseEvent>
# include "ShowScreenWindow.h"
# include "ConnectionWindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->m_ui.setupUi(this);
	this->m_showWindow = new ShowScreenWindow(this->m_ui.main);

	// connectionWindow
	this->m_connectionWindow = new ConnectionWindow(this->m_ui.main);
	this->connect(this->m_connectionWindow, &ConnectionWindow::connectButton, this, &MainWindow::onConnect);
	this->connect(this->m_connectionWindow, &ConnectionWindow::messageInput, this, &MainWindow::onMessageInput);
	// 隐藏窗口标题栏
	this->setWindowFlags(Qt::FramelessWindowHint);
	// setAttribute(Qt::WA_TranslucentBackground);     //窗口透明
    // 设置自定义标题栏
    this->m_toolbar = new ToolBar(this->m_ui.toolBar);
	
    this->connect(this->m_toolbar, &ToolBar::moveMainWindow, this, &MainWindow::moveMainWindow);
    this->connect(this->m_toolbar, &ToolBar::closeMainWindow, this, [=]() {
		this->close();
    });

	// 设置左侧选项
	this->m_settingbar = new SettingBar(this->m_ui.settingBar);
	this->connect(this->m_settingbar, &SettingBar::changeMain, this, &MainWindow::changeMain);
	this->connect(this->m_settingbar, &SettingBar::screenWindow, this, &MainWindow::screenWindow);
	this->connect(this->m_settingbar, &SettingBar::stopScreen, this, &MainWindow::stopScreen);
	this->connect(this->m_settingbar, &SettingBar::record, this, &MainWindow::record);
	this->connect(this->m_settingbar, &SettingBar::stopRecord, this, &MainWindow::stopRecord);
}

void MainWindow::moveMainWindow(QPoint point) {
    this->move(point);
}

MainWindow::~MainWindow()
{
    delete this->m_toolbar;
	delete this->m_showWindow;
	delete this->m_connectionWindow;
}

int MainWindow::runUi(int argc, char* argv[], MainWindow** _window, std::atomic_bool* _ui_state, std::function<void(void)> _callback)
{
	QApplication application(argc, argv);
	QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
	MainWindow* window = new MainWindow();
	(*_window) = window;
	_callback();
	window->show();
	int ret = application.exec();
	(*_ui_state) = false;
	return ret;
}

void MainWindow::log(const QString& _message)
{
	this->m_connectionWindow->log(_message);
}

void MainWindow::frame()
{
	this->m_showWindow->renderToTexture(this->m_showCursor);
	this->m_showWindow->rend();
}

void MainWindow::copyFromRenderTarget(uint8_t* _buffer, size_t size)
{
	if (this->m_showWindow == nullptr) {
		return;
	}
	this->m_showWindow->copyFromRenderTarget(_buffer, size);
}

void MainWindow::videoCaptureToShowWindow(ID3D11Device* _device, ID3D11DeviceContext* _context, ID3D11Texture2D* _monitor_texture)
{
	if (this->m_showWindow == nullptr) {
		return;
	}
	this->m_showWindow->copyMonitor(_device, _context, _monitor_texture);
}

void MainWindow::changeMain(QString windowName)
{
	if (windowName.contains(QString("playWindow"))) {
		this->createShowScreenWindow();
		this->m_connectionWindow->setVisible(false);
	}
	if (windowName.contains(QString("connectWindow"))) {
		this->m_connectionWindow->setVisible(true);
		this->clearShowScreenWindow();
	}
}

void MainWindow::record()
{
	this->onRecordCallback("out.mp4");
}

void MainWindow::stopRecord()
{
	this->onRecordStopCallbcak();
}

void MainWindow::screenWindow(int index)
{
	this->onScreenCallback(index, &m_videoCaptureWidth, &m_videoCaptureHeight);
	this->m_showWindow->addMonitor(m_videoCaptureWidth, m_videoCaptureHeight);
}

void MainWindow::stopScreen()
{
	this->onScreenStopCallback();
	this->m_showWindow->removeMonitor();
	m_videoCaptureWidth = 0;
	m_videoCaptureHeight = 0;
}

void MainWindow::onConnect(short port)
{
	this->onConnectCallback(port);
}

void MainWindow::onMessageInput(const QString& _message)
{
	this->onMessageInputCallback(_message);
}

void MainWindow::createShowScreenWindow()
{
	this->m_showWindow->removeMonitor();
	this->m_showWindow->setVisible(true);
	if (this->m_videoCaptureWidth != 0 || this->m_videoCaptureHeight != 0) {
		this->m_showWindow->removeMonitor();
		this->m_showWindow->addMonitor(this->m_videoCaptureWidth, this->m_videoCaptureHeight);
	}
}

void MainWindow::clearShowScreenWindow()
{
	this->m_showWindow->setVisible(false);
}
